package blue.http.core.options;

import blue.http.core.exception.HttpServerException;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLException;
import java.io.File;
import java.io.InputStream;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;

/**
 * @author Jin Zheng
 * @since 1.0 2021-08-12
 */
public class SslOptions {
	private static Logger logger = LoggerFactory.getLogger(SslOptions.class);

	private SslContext sslContext;
	private boolean enable = false;
	private File keyCertChainFile;
	private File keyFile;
	private InputStream keyCertChainIs;
	private InputStream keyIs;
	private X509Certificate[] keyCertChains;
	private PrivateKey key;

	public SslOptions() {
	}

	public void check() {
		if (!enable)
			return;

		SslContextBuilder builder = null;
		if (keyCertChains != null && keyCertChains.length > 0 && key != null) {
			builder = SslContextBuilder.forServer(key, keyCertChains);
		} else if (keyCertChainIs != null && keyIs != null) {
			builder = SslContextBuilder.forServer(keyCertChainIs, keyIs);
		} else if (keyCertChainFile != null && keyFile != null) {
			builder = SslContextBuilder.forServer(keyCertChainFile, keyFile);
		}

		if (builder == null)
			throw new HttpServerException("Invalid keyCertChain and key");

		try {
			sslContext = builder.build();
		} catch (SSLException e) {
			logger.error("Build SslContext error, ", e);
		}
	}

	public SslContext getSslContext() {
		return sslContext;
	}

	public boolean isEnable() {
		return enable;
	}

	public SslOptions setEnable(boolean enable) {
		this.enable = enable;
		return this;
	}

	public File getKeyCertChainFile() {
		return keyCertChainFile;
	}

	public SslOptions setKeyCertChainFile(File keyCertChainFile) {
		this.keyCertChainFile = keyCertChainFile;
		return this;
	}

	public File getKeyFile() {
		return keyFile;
	}

	public SslOptions setKeyFile(File keyFile) {
		this.keyFile = keyFile;
		return this;
	}

	public InputStream getKeyCertChainIs() {
		return keyCertChainIs;
	}

	public SslOptions setKeyCertChainIs(InputStream keyCertChainIs) {
		this.keyCertChainIs = keyCertChainIs;
		return this;
	}

	public InputStream getKeyIs() {
		return keyIs;
	}

	public SslOptions setKeyIs(InputStream keyIs) {
		this.keyIs = keyIs;
		return this;
	}

	public X509Certificate[] getKeyCertChains() {
		return keyCertChains;
	}

	public SslOptions setKeyCertChains(X509Certificate[] keyCertChains) {
		this.keyCertChains = keyCertChains;
		return this;
	}

	public PrivateKey getKey() {
		return key;
	}

	public SslOptions setKey(PrivateKey key) {
		this.key = key;
		return this;
	}
}
